package com.xuecheng.base.exception;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;


import java.nio.file.AccessDeniedException;
import java.util.ArrayList;

/**
 * @author: Hes
 * @description 全局异常处理器
 * @date: 2023/6/20 17:04
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
    @ResponseBody
    @ExceptionHandler(XueChengPlusException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public RestErrorResponse customException(XueChengPlusException e) {
        log.error("【系统异常】{}", e.getErrMessage(), e);
        return new RestErrorResponse(e.getErrMessage());

    }

    /**
     * JSR303引入后，异常会出现MethodArgumentNotValidException，这里统一处理去除默认de提示（就是在属性用注解上标记的）
     *
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public RestErrorResponse methodArgumentNotValidException(MethodArgumentNotValidException e) {
        BindingResult bindingResult = e.getBindingResult();
        ArrayList<String> strings = new ArrayList<>();
        bindingResult.getFieldErrors().stream().forEach(item -> {
            strings.add(item.getDefaultMessage());
        });
        String msg = StringUtils.join(strings, ",");
        log.error("【系统异常】{}", msg);
        return new RestErrorResponse(msg);

    }

    /**
     * 引入资源服务授权时，@PreAuthorize("hasAuthority('权限标识符')")的异常，这里统一处理
     * org.springframework.security.access.AccessDeniedException: 不允许访问
     * 这里不能引入spring security来接管base，那样就会被接管，请求都会拦截，
     * 这里只做了判断
     *
     * @param e
     * @return
     */

    @ResponseBody
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public RestErrorResponse exception(Exception e) {
        log.error("【系统异常】{}", e.getMessage(), e);
        if (e.getMessage().equals("不允许访问")) {
            return new RestErrorResponse("没有操作此功能的权限");
        }
        return new RestErrorResponse(CommonError.UNKOWN_ERROR.getErrMessage());

    }

}
